import { useParams } from 'common' import { Database } from 'icons' import { Loader2, Trash } from 'lucide-react' import Link from 'next/link' import { useRouter } from 'next/router' import { useEffect, useMemo, useState } from 'react' import { AWS_REGIONS } from 'shared-data' import { Badge, Button } from 'ui' import { ShimmeringLoader } from 'ui-patterns' import { ReadReplicaDetails } from '@/components/interfaces/Database/Replication/ReadReplicas/ReadReplicaDetails' import { getIsInTransition, getStatusLabel, } from '@/components/interfaces/Database/Replication/ReadReplicas/ReadReplicas.utils' import { DropReplicaConfirmationModal } from '@/components/interfaces/Settings/Infrastructure/InfrastructureConfiguration/DropReplicaConfirmationModal' import { REPLICA_STATUS } from '@/components/interfaces/Settings/Infrastructure/InfrastructureConfiguration/InstanceConfiguration.constants' import { RestartReplicaConfirmationModal } from '@/components/interfaces/Settings/Infrastructure/InfrastructureConfiguration/RestartReplicaConfirmationModal' import DatabaseLayout from '@/components/layouts/DatabaseLayout/DatabaseLayout' import { DefaultLayout } from '@/components/layouts/DefaultLayout' import { PageLayout } from '@/components/layouts/PageLayout/PageLayout' import { ScaffoldDescription, ScaffoldTitle } from '@/components/layouts/Scaffold' import { ButtonTooltip } from '@/components/ui/ButtonTooltip' import CopyButton from '@/components/ui/CopyButton' import { useReadReplicasQuery } from '@/data/read-replicas/replicas-query' import { ReplicaInitializationStatus, useReadReplicasStatusesQuery, } from '@/data/read-replicas/replicas-status-query' import type { NextPageWithLayout } from '@/types' const DatabaseReadReplicaPage: NextPageWithLayout = () => { const router = useRouter() const { ref, replicaId } = useParams() const [showConfirmRestart, setShowConfirmRestart] = useState(false) const [showConfirmDrop, setShowConfirmDrop] = useState(false) const [statusRefetchInterval, setStatusRefetchInterval] = useState(5000) const { data: databases = [], isPending: isLoadingDatabases, isSuccess: isSuccessDatabases, } = useReadReplicasQuery({ projectRef: ref }) const replica = databases.find((x) => x.identifier === replicaId) const { identifier, region, status: baseStatus } = replica ?? {} const { data: statuses = [], isSuccess: isSuccessReplicasStatuses } = useReadReplicasStatusesQuery({ projectRef: ref }, { refetchInterval: statusRefetchInterval }) const replicaStatus = statuses.find((x) => x.identifier === identifier) const status = replicaStatus?.status ?? baseStatus const initStatus = replicaStatus?.replicaInitializationStatus?.status const regionLabel = Object.values(AWS_REGIONS).find((x) => x.code === region)?.displayName const statusLabel = useMemo(() => getStatusLabel({ initStatus, status }), [initStatus, status]) const isInTransition = useMemo( () => getIsInTransition({ initStatus, status }), [initStatus, status] ) useEffect(() => { if (!isSuccessReplicasStatuses) return const pollReplicas = async () => { const fixedStatuses = [ REPLICA_STATUS.ACTIVE_HEALTHY, REPLICA_STATUS.ACTIVE_UNHEALTHY, REPLICA_STATUS.INIT_READ_REPLICA_FAILED, ] const replicasInTransition = statuses.filter((db) => { const { status } = db.replicaInitializationStatus || {} return ( !fixedStatuses.includes(db.status) || status === ReplicaInitializationStatus.InProgress ) }) const hasTransientStatus = replicasInTransition.length > 0 // If all replicas are active healthy, stop fetching statuses if (!hasTransientStatus && statuses.length === databases.length) { setStatusRefetchInterval(false) } } pollReplicas() }, [databases.length, isSuccessReplicasStatuses, statuses]) return ( Read Replica {isSuccessDatabases && ( <> {statusLabel} {isInTransition && } )} } subtitle={ isLoadingDatabases ? ( ) : (
ID: {identifier}
) } icon={
} breadcrumbs={[ { label: 'Replication', href: `/project/${ref}/database/replication`, }, { label: `Read Replica - ${regionLabel}`, }, ]} secondaryActions={ } tooltip={{ content: { side: 'bottom', text: 'Drop replica' }, }} onClick={() => setShowConfirmDrop(true)} /> } primaryActions={[ , , ]} > router.push(`/project/${ref}/database/replication`)} onCancel={() => setShowConfirmDrop(false)} /> setStatusRefetchInterval(5000)} onCancel={() => setShowConfirmRestart(false)} />
) } DatabaseReadReplicaPage.getLayout = (page) => ( {page} ) export default DatabaseReadReplicaPage